package com.ruihui.activity.service.impl;

import com.ruihui.activity.pojo.Accoupon;
import com.ruihui.activity.pojo.Acgoods;
import com.ruihui.activity.pojo.Acgroup;
import com.ruihui.activity.exceprion.ManualException;
import com.ruihui.activity.mapper.AcgroupMapper;
import com.ruihui.activity.service.AcgroupService;
import com.ruihui.activity.util.DateUtil;
import com.ruihui.activity.util.StringUUIDUtil;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;

import static com.google.common.base.Preconditions.checkArgument;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * <p>
 * 团购 服务实现类
 * </p>
 *
 * @author cf123
 * @since 2018-10-29
 */
@Service
public class AcgroupServiceImpl extends ServiceImpl<AcgroupMapper, Acgroup> implements AcgroupService {
	@Autowired
	private AcgroupMapper acgroupMapper;

	@Override
	public int getCreateCount(Integer memberId, Long goodsid, Acgoods acgoods) {
		int addcount = acgroupMapper.selectCount(new EntityWrapper<Acgroup>().eq("userid", memberId)
				.in("state", Acgroup.NOTDISMISS).between("createtime", acgoods.getStarttime(), acgoods.getEndtime())
				.eq("goodsid", goodsid).eq("type", Acgroup.HEAD).eq("paystatus", Acgroup.OP));
		return addcount;
	}

	@Override
	public int getAddCount(Integer memberId, Long goodsid, Acgoods acgoods) {
		int addcount = acgroupMapper.selectCount(new EntityWrapper<Acgroup>().eq("userid", memberId)
				.in("state", Acgroup.NOTDISMISS).between("createtime", acgoods.getStarttime(), acgoods.getEndtime())
				.eq("goodsid", goodsid).eq("type", Acgroup.MEMBER).eq("paystatus", Acgroup.OP));
		return addcount;
	}

	@Override
	public int createGroup(Acgoods acgoods, Integer memberId, Long goodsid, Long orderid, String username) {
		long nowdate = DateUtil.getDateline();
		// 生成团号
		String acgroupno = StringUUIDUtil.createPonUUID(acgoods.getGname(), memberId);
		// 24小时后的时间
		long endtime = DateUtil.GetDateTimeToNumber(new Date(nowdate * 1000), 1).getTime() / 1000;
		/*
		 * 创建团组
		 */
		Acgroup acgroup = new Acgroup();
		acgroup.setOrderid(orderid);
		acgroup.setGoodsid(goodsid);
		acgroup.setUserid(memberId.longValue());
		acgroup.setUsername(username);
		acgroup.setState(Acgroup.NO);
		acgroup.setType(Acgroup.HEAD);
		acgroup.setStarttime(new BigDecimal(nowdate));
		acgroup.setCreatetime(new BigDecimal(nowdate));
		if (StringUtils.isEmpty(acgoods.getContents())) {
			acgroup.setContents(acgoods.getContents());
		}
		acgroup.setPernumber(acgoods.getGroupnum());
		acgroup.setGacid(acgoods.getId());
		acgroup.setPaystatus(Acgroup.OP);
		acgroup.setEndtime(new BigDecimal(endtime));
		acgroup.setGroupno(acgroupno);
		Integer flg = acgroupMapper.insert(acgroup);
		return flg.intValue();
	}

	@Override
	@Transactional
	public int addGroup(Integer memberId, String groupno, Long orderid, String username) {
		long nowdate = DateUtil.getDateline();
		// 验证是否未成团
		List<Acgroup> acgroups = this.validateAcgroup(groupno);
		/*
		 * 加入团组
		 */
		Acgroup acgroup = acgroups.get(0);
		acgroup.setOrderid(orderid);
		acgroup.setUserid(memberId.longValue());
		acgroup.setUsername(username);
		if ((acgroups.size() + 1) < acgroup.getPernumber().intValue()) {
			acgroup.setState(Acgroup.NO);
		} else if ((acgroups.size() + 1) == acgroup.getPernumber().intValue()) {
			acgroup.setState(Acgroup.YES);
			// 将团组所有人修改成成团
			int upa = acgroupMapper.updateAllState(groupno);
			checkArgument(upa >= 1, "修改团组状态失败");
		} else {
			throw new ManualException(-1, "团组已满");
		}
		acgroup.setType(Acgroup.MEMBER);
		acgroup.setCreatetime(new BigDecimal(nowdate));
		Integer flg = acgroupMapper.insert(acgroup);
		// 再次验证
		acgroups = this.getAcgroups(groupno);
		checkArgument(acgroups.size() <= acgroup.getPernumber().intValue(), "团组已满");
		return flg.intValue();
	}

	@Override
	public List<Acgroup> validateAcgroup(String groupno) {
		long nowdate = DateUtil.getDateline();
		List<Acgroup> acgroups = acgroupMapper.selectList(new EntityWrapper<Acgroup>().eq("paystatus", Acgroup.OP)
				.eq("groupno", groupno).where("{0} between starttime and endtime", nowdate));
		// 双重验证
		checkArgument(acgroups.size() > 0 && acgroups.size() < acgroups.get(0).getPernumber().intValue(), "已满员或已经解散");
		return acgroups;
	}

	private List<Acgroup> getAcgroups(String groupno) {

		List<Acgroup> acgroups = acgroupMapper
				.selectList(new EntityWrapper<Acgroup>().eq("paystatus", Acgroup.OP).eq("groupno", groupno));
		return acgroups;
	}

	@Override
	@Transactional
	public int backGroup(Integer memberId, String groupno) {
		long nowdate = DateUtil.getDateline();
		Integer userCode = -1;
		Integer groupCode = -1;
		// 条件
		Acgroup ac = new Acgroup();
		ac.setUserid(memberId.longValue());
		ac.setGroupno(groupno);
		ac.setPaystatus(Acgroup.OP);
		// 未成团状态
		Acgroup updstate = new Acgroup();
		updstate.setState(Acgroup.NO);
		// 支付状态
		Acgroup updac = new Acgroup();
		updac.setPaystatus(Acgroup.OSB);
		// 退出人员信息
		List<Acgroup> acg = acgroupMapper
				.selectList(new EntityWrapper<Acgroup>(ac).where("{0} between starttime and endtime", nowdate));

		checkArgument(acg.size() == 1, "团组已经解散或您已经成功退出，系统将自动进行退款处理");
		// 是否团长
		boolean ishead = acg.get(0).getType().intValue() == Acgroup.HEAD.intValue();
		/*
		 * 修改用户支付状态
		 */
		userCode = acgroupMapper.update(updac, new EntityWrapper<Acgroup>(ac));
		checkArgument(userCode.intValue() == 1, "退出失败");
		/*
		 * 修改团组信息
		 */
		ac.setUserid(null);
		// 团组所有人员信息
		List<Acgroup> acgs = acgroupMapper.selectList(new EntityWrapper<Acgroup>(ac));
		if (acgs.size() == 0 || acgs.isEmpty()) {// 人员全部退出

		} else if (ishead) {// 否则，若是团长退出则新任一名团长
			Acgroup newHead = acgs.get(0);
			newHead.setType(Acgroup.HEAD);
			Integer nhcode = acgroupMapper.updateById(newHead);
			checkArgument(nhcode.intValue() == 1, "任命团长失败导致退团失败");
			// 修改团组状态
			groupCode = acgroupMapper.update(updstate, new EntityWrapper<Acgroup>(ac));
		} else {// 否则，若不是团长退出直接修改团组状态
			groupCode = acgroupMapper.update(updstate, new EntityWrapper<Acgroup>(ac));
		}
		checkArgument(groupCode.intValue() >= 1, "修改团组状态失败导致退团失败");
		return userCode;
	}

	@Override
	@Transactional
	public int backpay(Integer memberId, Long orderid, Integer otype) {
		int backpayCode = 0;
		// 退款或者申请退款状态
		Acgroup updstate = new Acgroup();
		updstate.setPaystatus(otype);

		backpayCode = acgroupMapper.update(updstate,
				new EntityWrapper<Acgroup>().eq("userid", memberId).eq("orderid", orderid).notIn("paystatus", otype));

		checkArgument(backpayCode == 1, "团组用户信息修改失败，请检查");
		return backpayCode;
	}

	@Override
	public boolean isHead(Integer memberId, String groupno) {
		int code = acgroupMapper.selectCount(
				new EntityWrapper<Acgroup>().eq("userid", memberId).eq("groupno", groupno).eq("type", Acgroup.HEAD));
		checkArgument(code <= 1, "数据异常，请检查");
		return code == 1;
	}

}
